package org.jetlinks.pro.notify.wechat;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.web.exception.BusinessException;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.HashMap;

/**
 * @author gyl
 * @version 1.0
 * @time 2021/11/22 16:14
 */
@Slf4j
public class WeixinGeneralRequest {

    public static Mono<Void> sendPost(WebClient client, String url, JSONObject body) {
        return client.post()
                     .uri(url)
                     .contentType(MediaType.APPLICATION_JSON)
                     .bodyValue(body)
                     .retrieve()
                     .bodyToMono(JSONObject.class)
                     .as(WeixinGeneralRequest::checkResult)
                     .then();
    }

    public static Mono<JSONObject> sendGet(WebClient client, String url) {
        return client.get()
                     .uri(url)
                     .retrieve()
                     .bodyToMono(JSONObject.class);
    }


    /**
     * 微信返回码说明：https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Global_Return_Code.html
     *
     * @param msg
     * @return
     */
    private static Mono<JSONObject> checkResult(Mono<JSONObject> msg) {
        return msg.doOnNext(json -> {
            String code = String.valueOf(json.get("errcode"));
            if (!"0".equals(code)) {
                log.warn("发送微信通知失败:{}", json);
                throw new BusinessException("发送微信通知失败:" + json, code);
            }
        });
    }

    public static Mono<String> requestToken(WebClient client, URI uri) {
        return client
            .get()
            .uri(uri)
            .exchange()
            .flatMap(resp -> resp.bodyToMono(HashMap.class))
            .map(map -> {
                if (map.containsKey("access_token")) {
                    return map.get("access_token");
                }
                throw new BusinessException("获取Token失败:" + map.get("errmsg"), String.valueOf(map.get("errcode")));
            })
            .cast(String.class);
    }


}
